package com.losl.framework.config;

import com.losl.framework.security.JwtAuthenticationTokenFilter;
import com.losl.framework.web.service.LogoutHandlerImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.authentication.logout.LogoutFilter;
import org.springframework.security.web.authentication.rememberme.JdbcTokenRepositoryImpl;
import org.springframework.security.web.authentication.rememberme.PersistentTokenRepository;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;

import javax.sql.DataSource;
import java.util.Arrays;

/**
 * springsecurity配置类
 * @author Maxwell
 */
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    //配置对象
    @Autowired
    private UserDetailsService userDetailService;
    //注入数据源
    @Autowired
    private DataSource dataSource;

    @Autowired
    private LogoutHandlerImpl logoutHandler;

    @Bean
    public PersistentTokenRepository persistentTokenRepository() {
        JdbcTokenRepositoryImpl jdbcTokenRepository = new JdbcTokenRepositoryImpl();
        jdbcTokenRepository.setDataSource(dataSource);
        return jdbcTokenRepository;
    }

    /**
     * 调用UserDetailsService的实现类来进行验证
     */
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailService).passwordEncoder(passwordEncoder());
    }

    /**
     * 设置密码加密
     */
    @Bean
    public BCryptPasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    /**
     * springsecurity的配置
     * 更改默认的登陆页面和策略
     */
    @Override
    protected void configure(HttpSecurity httpSecurity) throws Exception {
        httpSecurity.csrf().disable().httpBasic();//关闭csrf安全防护

        httpSecurity
                .authorizeRequests()//定义那些url被保护那些不被保护
                .antMatchers(HttpMethod.OPTIONS,"/**").permitAll()
                //swagger2有关的权限
                .antMatchers("/swagger-ui.html").permitAll()
                .antMatchers("/webjars/**").permitAll()
                .antMatchers("/v2/**").permitAll()
                .antMatchers("/swagger-resources/**").permitAll()
                .antMatchers("/", "/captcha", "/login", "/register","/test","/user/post").permitAll()//定义那些可以直接访问不需要验证
                .antMatchers("/user/detail", "/user/update", "/user/update/password").permitAll()
                .antMatchers("/posts/page", "/posts/list", "/posts/update","/posts/index",
                        "/posts/single/*", "/posts/save", "/posts/del/*", "/posts/status").permitAll()
                .antMatchers("/comment/page", "/comment/list", "/comment/update",
                        "/comment/single/*", "/comment/save", "/comment/del/*", "/comment/status").permitAll()
                .antMatchers("/notice/page", "/notice/list", "/notice/update",
                        "/notice/single/*", "/notice/save", "/notice/del/*", "/notice/status").permitAll()
                .antMatchers("/userFollow/page", "/userFollow/list", "/userFollow/update",
                        "/userFollow/single/*", "/userFollow/save", "/userFollow/del/*", "/userFollow/status").permitAll()
                .antMatchers("/userLike/page", "/userLike/list", "/userLike/update",
                        "/userLike/single/*", "/userLike/save", "/userLike/del/*", "/userLike/status").permitAll()
                .anyRequest().authenticated()
                .and().cors();


        httpSecurity.addFilterBefore(authenticationTokenFilter, UsernamePasswordAuthenticationFilter.class);
        // 添加CORS filter
        httpSecurity.addFilterBefore(corsFilter, LogoutFilter.class);
        httpSecurity.logout().logoutUrl("/logout").logoutSuccessHandler(logoutHandler);
    }

    @Autowired
    private JwtAuthenticationTokenFilter authenticationTokenFilter;

    @Autowired
    private CorsFilter corsFilter;

    @Bean
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }
}
